<template>
	<picker-view
		style="width:750rpx;"
		:style="{ height: innerPickerHeight + 'px' }"
		:indicator-style="'height:' + innerPickerHeight / indicatorNum + 'px'"
		:value="pickerValue"
		@change="pickerChange"
	>
		<picker-view-column>
			<view class="flex-center text-hide" v-for="(item, index) in yearData" :key="item.value">
				<text class="text-m" :class="[pickerValue[0] === index ? 'color-active' : 'color-main']">
					{{ item.text }}
				</text>
			</view>
		</picker-view-column>
		<picker-view-column v-if="mode === 'm' || mode === 'd'">
			<view class="flex-center text-hide" v-for="(item, index) in monthData" :key="item.value">
				<text class="text-m" :class="[pickerValue[1] === index ? 'color-active' : 'color-main']">
					{{ item.text }}
				</text>
			</view>
		</picker-view-column>
		<picker-view-column v-if="mode === 'd'">
			<view class="flex-center text-hide" v-for="(item, index) in dayData" :key="item.value">
				<text class="text-m" :class="[pickerValue[2] === index ? 'color-active' : 'color-main']">
					{{ item.text }}
				</text>
			</view>
		</picker-view-column>
	</picker-view>
</template>

<script>
import { ref, watch, nextTick } from 'vue';
import { getRange, paddingZero } from '../../../utils/common.js';
import dateUtil from '../../../utils/date.js';
import Calendar from '../../lib/datetime-picker/calendar.js';

export default {
	props: {
		pickerHeight: {
			default: 550,
			type: Number,
		},
		indicatorNum: {
			default: 5,
			type: Number,
		},
		//xxxx-xx-xx
		modelValue: {
			default: '',
			type: String,
		},
		//y m d
		mode: {
			default: 'd',
			type: String,
		},
		maxDate: Object,
	},
	setup(props, ctx) {
		/**
		 * value
		 */
		const pickerValue = ref([]);
		let triggerPickerChange = true;
		function pickerChange(e) {
			if(!triggerPickerChange) return;
			console.log("===========>pickerChange", e);
			valueChange(e.detail.value);
		}
		let changeInter = null;
		async function valueChange(newValue) {
			if(changeInter !== null){
				clearTimeout(changeInter);
			}
			triggerPickerChange = false;
			pickerValue.value = newValue;
			if (props.mode === 'd' || props.mode === "m") {
				const valObj = indexToValue(pickerValue.value);
				console.log("=====>valueChange", newValue, valObj);
				const newMonthData = getMonthData(valObj.year);
				if (newMonthData.length !== monthData.value.length) {
					//长度不同 数据要更新
					monthData.value = newMonthData;
					//列表数据更新后 需nextTIck 再更新pickerValue
					await nextTick();
					pickerValue.value = valueToIndex(props.modelValue);
					const newValObj = indexToValue(pickerValue.value);
					const index = newMonthData.findIndex((el) => el.value === newValObj.month);
					if (index === -1) {
						//month value需更新
						const newValue = [...pickerValue.value];
						newValue[1] = newMonthData.length - 1;
						pickerValue.value = newValue;
					}
				}
				if(props.mode === 'd'){
					const newDayData = getDayData(valObj.year, valObj.month);
					if (newDayData.length !== dayData.value.length) {
						//长度不同 日数据要更新
						dayData.value = newDayData;
						await nextTick();
						pickerValue.value = valueToIndex(props.modelValue);
						const newValObj = indexToValue(pickerValue.value);
						// console.log("======>dayData updated", pickerValue.value, newValObj);
						const index = newDayData.findIndex((el) => el.value === newValObj.day);
						if (index === -1) {
							//day value需更新
							const newValue = [...pickerValue.value];
							newValue[2] = newDayData.length - 1;
							pickerValue.value = newValue;
						}
					}
				}
			}
			const valObj = indexToValue(pickerValue.value);
			const result = [];
			['year', 'month', 'day'].forEach((key) => {
				if (valObj[key] !== null) {
					result.push(paddingZero(valObj[key]));
				}
			});
			ctx.emit('update:modelValue', result.join('-'));
			//莫名触发pickerChange事件，暂时不知道原因，先用setTimeout解决
			changeInter = setTimeout(() => {
				triggerPickerChange = true;
				changeInter = null;
			}, 300);
		}
		/**
		 * data
		 */
		const yearData = getRange(1970, props.maxDate ? props.maxDate.getFullYear() : 2100, {
			formatter(v) {
				return { text: v + '年', value: v };
			},
		});
		const monthData = ref([]);
		const dayData = ref([]);
		function getDayData(y, m) {
			const maxDate = props.maxDate;
			const maxDay = (maxDate && maxDate.getFullYear() === y && maxDate.getMonth() + 1 === m) ? maxDate.getDate() : Calendar.solarDays(y, m);
			return getRange(1, maxDay, {
				formatter(v) {
					return { text: v + '日', value: v };
				},
			});
		}
		function getMonthData(y) {
			const maxDate = props.maxDate;
			const maxMonth = maxDate && maxDate.getFullYear() === y ? maxDate.getMonth() + 1 : 12;
			return getRange(1, maxMonth, {
				formatter(v) {
					return { text: v + '月', value: v };
				},
			});
		}
		function indexToValue(indexVal) {
			return {
				year: isValidIndex(indexVal[0], yearData) ? yearData[indexVal[0]].value : null,
				month: isValidIndex(indexVal[1], monthData.value) ? monthData.value[indexVal[1]].value : null,
				day: isValidIndex(indexVal[2], dayData.value) ? dayData.value[indexVal[2]].value : null,
			};
		}
		function isValidIndex(index, data) {
			return index !== undefined && data[index] !== undefined;
		}
		function setValueByDate(date) {
			const y = date.getFullYear();
			const m = date.getMonth() + 1;
			const d = date.getDate();
			const vals = [];
			const yIndex = yearData.findIndex((el) => el.value === y);
			vals.push(yIndex);
			monthData.value = getMonthData(y);
			dayData.value = getDayData(y, m);
			if (props.mode === 'm') {
				const mIndex = monthData.value.findIndex((el) => el.value === m);
				vals.push(mIndex);
			}
			if (props.mode === 'd') {
				const dIndex = dayData.value.findIndex((el) => el.value === d);
				vals.push(dIndex);
			}
			pickerValue.value = vals;
		}
		setValueByDate(new Date());
		const innerPickerHeight = ref(uni.upx2px(props.pickerHeight));
		//xxxx-xx-xx value要转化为索引
		function valueToIndex(value){
			if (!value) {
				value = dateUtil.format(new Date());
			}
			//xxxx-xx-xx value要转化为索引
			const vals = value.split('-');
			const indexVals = [];
			const yIndex = yearData.findIndex((el) => el.value === parseInt(vals[0]));
			indexVals.push(yIndex);
			if (vals[1]) {
				const mIndex = monthData.value.findIndex((el) => el.value === parseInt(vals[1]));
				indexVals.push(mIndex);
			}
			if (vals[2]) {
				const dIndex = dayData.value.findIndex((el) => el.value === parseInt(vals[2]));
				indexVals.push(dIndex);
			}
			return indexVals;
		}
		watch(
			() => props.modelValue,
			(value) => {
				console.log("=====>modelValue change", value);
				const indexVals = valueToIndex(value);
				valueChange(indexVals);
			},
			{
				immediate: true,
			}
		);
		return {
			pickerChange,
			pickerValue,
			yearData,
			monthData,
			dayData,
			innerPickerHeight,
		};
	},
};
</script>

<style></style>
